package tips.p_1000.p301_350;

/**
 * 初始时有 n 个灯泡处于关闭状态。
 * 对某个灯泡切换开关意味着：如果灯泡状态为关闭，那该灯泡就会被开启；而灯泡状态为开启，那该灯泡就会被关闭。
 * 第 1 轮，每个灯泡切换一次开关。即，打开所有的灯泡。
 * 第 2 轮，每两个灯泡切换一次开关。 即，每两个灯泡关闭一个。
 * 第 3 轮，每三个灯泡切换一次开关。
 * 第 i 轮，每 i 个灯泡切换一次开关。 而第 n 轮，你只切换最后一个灯泡的开关。
 * 找出 n 轮后有多少个亮着的灯泡。
 * <p>示例 1：
 * 输入：n = 3
 * 输出：1
 * 解释：
 * 初始时, 灯泡状态 [关闭, 关闭, 关闭].
 * 第一轮后, 灯泡状态 [开启, 开启, 开启].
 * 第二轮后, 灯泡状态 [开启, 关闭, 开启].
 * 第三轮后, 灯泡状态 [开启, 关闭, 关闭].
 * 你应该返回 1，因为只有一个灯泡还亮着。
 * <p>示例 2：
 * 输入：n = 0
 * 输出：0
 * <p>示例 3
 * 输入：n = 1
 * 输出：1
 * <p>提示：0 <= n <= 10^9
 *
 * @author hc
 */
public class Demo319 {

    /**
     * 首先思考：灯泡 k 会被按几次？这其实相当于求 k 有几个因子 比如灯泡 8 ,一共会被按 4 次，分别是第一轮 第二轮 第四轮 第八轮
     * <p>所以，初始有 n 个灯泡关闭
     * 第 i 轮的操作是每 i 个灯泡切换一次开关（开->闭，闭->开），即切换 i 的倍数位置的开关。
     * 求 n 轮后亮着的灯泡？
     * <p>(1)第 i 轮时，被切换的灯泡位置是 i 的倍数。
     * <p>(2)由（1）得出，对于第 p 个灯泡来说，只有其第“因子”轮才会切换，若其有 q 个因子，则最终被切换 q 次。
     * 因为初始状态是关闭状态，那么因子数是奇数的灯泡最终是亮着的。
     * <p>(3)只有平方数的因子个数不是成对出现，举例：4=1*4,2*2，其因子是 1,2,4。
     * <p>(4)那么题目最终转化为 1~n 里平方数的个数，进而转化为对 n 开平方根，向下取整即可。
     */
    public int bulbSwitch(int n) {
        if (n == 0 || n == 1) {return n;}
        return (int) Math.floor(Math.sqrt(n));
    }
}
